<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="rstyro-胖不了小陆">
    <title>国庆头像合成</title>
</head>
<style>
    * {
        margin: 0px;
        padding: 0px;
    }

    .container {
        width: 100%;
        height: 100vh;
        overflow: hidden;
        background-color: #ffe;
    }

    .main {
        width: 800px;
        margin: 20px auto;
        min-height: 800px;
        padding-top: 20px;
        position: relative;
        text-align: center;
        box-shadow:
                0.5px 2.1px 1.6px rgba(0, 0, 0, 0.028),
                1.1px 4.8px 3.8px rgba(0, 0, 0, 0.041),
                1.8px 8.3px 6.9px rgba(0, 0, 0, 0.051),
                2.9px 13.2px 11.4px rgba(0, 0, 0, 0.059),
                4.6px 20.5px 18.8px rgba(0, 0, 0, 0.069),
                7.3px 32.9px 32.8px rgba(0, 0, 0, 0.082),
                14px 63px 71px rgba(0, 0, 0, 0.11);
        background-image: linear-gradient(to top, #ff9a9e 0%, #fecfef 99%, #fecfef 100%);
    }

    h2{
        color: #fff;
        font-size: 36px;
        padding: 20px 0;
    }

    .icons {
        width: 100%;
        height: 101px;
        overflow-y: hidden;
        overflow-x: auto;
        display: flex;
        /*justify-content: space-evenly;*/
        padding: 10px 0px;
        margin-top: 10px;
    }

    .icons img {
        width: 100px;
        display: inline-block;
        border: 2px solid #fff;
    }

    .icons img:nth-child(n+2) {
        margin-left: 20px;
    }

    .main-body {
        clear: both;
        text-align: center;
    }

    .btn-box {
        display: flex;
        margin: 50px 0;
        justify-content: space-evenly;
    }

    .btn-box .btn {
        width: 120px;
        height: 40px;
        line-height: 40px;
        background-color: #0a8ee7;
        color: #fff;
        padding: 0 20px;
        text-align: center;
        cursor: pointer;
    }

    .btn:hover {
        color: #2af598;
    }

    /*滚动条样式*/
    ::-webkit-scrollbar {
        width: 0.5rem;
        height: 0.5rem;
        background-image: linear-gradient(135deg, #eee 0%, #ddd 72%, #ccc 100%);

    }

    /*定义滚动条滑块*/
    ::-webkit-scrollbar-thumb {
        background-color: #98dba1;
    }

    #canvas {
        margin-top: 50px;
    }
</style>
<body>
<div class="container" id="app">
    <div class="main">
        <h2>国庆头像合成Demo</h2>
        <div class="icons">
            <img v-for="(icon,index) of list" :src="icon" @click="selectIcon(index)">
        </div>
        <div class="main-body">
            <input v-show="false" ref="fileRef" id="uploadFile"
                   type="file" accept="image/*" @change="fileChange">
            <canvas id="canvas" ref="myCanvas" width="300" height="300"></canvas>
            <div class="btn-box">
                <div class="btn" @click="uploadAvatar">上传头像图片</div>
                <div class="btn" @click="downloadPic">下载图片</div>
            </div>
        </div>
    </div>
</div>
<!--<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>-->
<script src="../vue/vue.global.js"></script>
<script>
    //将vue对象绑定到window对象
    Object.assign(window, Vue);
    const vue3Composition = {
        setup() {
            const {onMounted, toRefs, reactive} = Vue;

            // 定义参数
            const data = reactive({
                fileRef: null,
                myCanvas: null,
                ctx: null,
                size: 300,
                list: [
                    "images/head0.png",
                    "images/head1.png",
                    "images/head2.png",
                    "images/head3.png",
                    "images/head4.png",
                    "images/head5.png",
                    "images/head7.png",
                    "images/head9.png",
                ],
                icon: "images/head3.png"
            });

            // 文件上传
            const uploadAvatar = () => {
                data.fileRef.dispatchEvent(new MouseEvent('click'));
            }

            // 选择边框
            const selectIcon = (index) => {
                data.icon = data.list[index];
                fileChange();
            }

            // 渲染图片
            const fileChange = () => {
                // 当input有修改就重新合成图片
                data.ctx.clearRect(0, 0, data.size, data.size);
                // if (data.fileRef.files.length > 0) {
                //     let avatarUrl = window.URL.createObjectURL(document.getElementById('uploadFile').files[0]);
                //     loadImag(avatarUrl);
                // } else {
                //     loadImag("images/default.png");
                // }
                // loadImag(data.icon);

                let avatarUrl = "images/default.png";
                if (data.fileRef.files.length > 0) {
                    avatarUrl = window.URL.createObjectURL(document.getElementById('uploadFile').files[0]);
                }
                loadImagAsync(avatarUrl)
                    .then(() => {
                        return loadImagAsync(data.icon);
                    }).then(() => {
                    console.log("合成成功...")
                })

            }

            // 画布加载图片
            // const loadImag = (imageUrl) => {
            //     let image = new Image;
            //     // 解决跨域 Canvas 污染问题
            //     image.setAttribute("crossOrigin", "anonymous");
            //     image.onload = () => {
            //         const imgW = image.width;
            //         const imgH = image.height;
            //         if (imgH > imgW) {
            //             // 宽度100% 高度自适应
            //             data.ctx.drawImage(image, 0, 0, data.size, imgH * data.size / imgW);
            //         } else {
            //             // 宽度自适应
            //             data.ctx.drawImage(image, 0, 0, imgW * data.size / imgH, data.size);
            //         }
            //
            //     }
            //     image.src = imageUrl;
            // }

            // 异步画布加载图片
            const loadImagAsync = (imageUrl) => {
                let image = new Image;
                // 解决跨域 Canvas 污染问题
                image.setAttribute("crossOrigin", "anonymous");
                image.src = imageUrl;
                return new Promise((resolve, reject) => {
                    image.onload = () => {
                        const imgW = image.width;
                        const imgH = image.height;
                        if (imgH > imgW) {
                            // 宽度100% 高度自适应
                            data.ctx.drawImage(image, 0, 0, data.size, imgH * data.size / imgW);
                        } else {
                            // 宽度自适应
                            data.ctx.drawImage(image, 0, 0, imgW * data.size / imgH, data.size);
                        }
                        // next
                        resolve();
                    };
                    image.onerror = () => {
                        reject(new Error('Could not load image at ' + imageUrl));
                    };

                });
            }

            // 图片下载
            const downloadPic = () => {
                //得到图片的base64编码数据
                let url = data.myCanvas.toDataURL("image/png");
                let a = document.createElement("a");
                // 创建一个单击事件
                let event = new MouseEvent("click");
                a.download = "img";
                a.href = url;
                // 触发a的单击事件
                a.dispatchEvent(event);
            }

            onMounted(() => {
                data.ctx = data.myCanvas.getContext('2d');
                fileChange();
            })

            return {
                uploadAvatar,
                selectIcon,
                fileChange,
                downloadPic,
                ...toRefs(data)
            }
        }
    }
    const app = createApp(vue3Composition).mount('#app');
</script>
</body>
</html>
